package com.example.test.common;

import com.example.test.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.crypto.spec.SecretKeySpec;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Key;
import java.util.Base64;
import java.util.Collections;
import java.util.Set;

public class JwtAuthenticationFilter extends OncePerRequestFilter {

	private static final String SECRET_KEY = "your-secret-key-must-be-at-least-32-characters-long"; // 确保密钥足够长
	private final Set<String> excludedPaths; // 白名单路径集合

	// 接受白名单路径
	public JwtAuthenticationFilter(Set<String> excludedPaths) {
		this.excludedPaths = excludedPaths;
	}

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws ServletException, IOException {

		String path = request.getRequestURI();

		// 如果当前请求路径在白名单中，跳过 JWT 认证
		if (excludedPaths.contains(path) || path.startsWith("/swagger")) {
			chain.doFilter(request, response);
			return;
		}

		String token = request.getHeader("Authorization");
		if (token != null && token.startsWith("Bearer ")) {
			token = token.substring(7); // 去掉 "Bearer "
			Claims claims = JwtUtil.parseToken(token);
			if (claims != null) {
				String username = claims.getSubject();
				Integer userId = claims.get("userId", Integer.class);
				User user = new User(username, "", Collections.emptyList());
				UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
				auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
				SecurityContextHolder.getContext().setAuthentication(auth);
			}
		}
		chain.doFilter(request, response);
	}

	private static Key getSigningKey() {
		byte[] keyBytes = Base64.getDecoder().decode(SECRET_KEY);
		return new SecretKeySpec(keyBytes, SignatureAlgorithm.HS256.getJcaName());
	}


}
